package com.southwind.controller;


import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.southwind.entity.ProductCategory;
import com.southwind.entity.ProductInfo;
import com.southwind.exception.ShopException;
import com.southwind.form.SellerProductForm;
import com.southwind.handler.CustomCellWriteHandler;
import com.southwind.result.ResponseEnum;
import com.southwind.service.ProductCategoryService;
import com.southwind.service.ProductInfoService;
import com.southwind.util.ResultVOUtil;
import com.southwind.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import org.springframework.stereotype.Controller;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品表 前端控制器
 * </p>
 *
 * @author southwind
 * @since 2025-02-12
 */
@RestController
@RequestMapping("/seller/product")
public class SellerProductController {

    @Autowired
    private ProductCategoryService categoryService;
    @Autowired
    private ProductInfoService infoService;

    @GetMapping("/findAllProductCategory")
    public ResultVO findAllProductCategory(){
        List<ProductCategory> categoryList = this.categoryService.list(null);
        List<SellerProductCategoryVO> list = new ArrayList<>();
        for (ProductCategory productCategory : categoryList) {
            SellerProductCategoryVO vo = new SellerProductCategoryVO();
            vo.setName(productCategory.getCategoryName());
            vo.setType(productCategory.getCategoryType());
            list.add(vo);
        }
        Map map = new HashMap();
        map.put("content", list);
        return ResultVOUtil.success(map);
    }

    @PostMapping("/add")
    public ResultVO add(@RequestBody ProductInfo productInfo){
        boolean save = this.infoService.save(productInfo);
        if(save) return ResultVOUtil.success(null);
        return ResultVOUtil.fail(ResponseEnum.PRODUCT_ADD_ERROR.getMsg());
    }

    @GetMapping("/list/{page}/{size}")
    public ResultVO list(
            @PathVariable("page") Integer page,
            @PathVariable("size") Integer size
    ){
        Page<ProductInfo> pageModel = new Page<>(page,size);
        Page<ProductInfo> resultPage = this.infoService.page(pageModel);
        List<SellerProductInfoVO> list = new ArrayList<>();
        for (ProductInfo record : resultPage.getRecords()) {
            SellerProductInfoVO vo = new SellerProductInfoVO();
            BeanUtils.copyProperties(record, vo);
            if(record.getProductStatus() == 1) {
                vo.setStatus(true);
            } else {
                vo.setStatus(false);
            }
            QueryWrapper<ProductCategory> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("category_type", record.getCategoryType());
            ProductCategory productCategory = this.categoryService.getOne(queryWrapper);
            vo.setCategoryName(productCategory.getCategoryName());
            list.add(vo);
        }
        PageVO pageVO = new PageVO();
        pageVO.setContent(list);
        pageVO.setSize(size);
        pageVO.setTotal(resultPage.getTotal());
        return ResultVOUtil.success(pageVO);
    }

    @GetMapping("/like/{keyWord}/{page}/{size}")
    public ResultVO like(
            @PathVariable("keyWord") String keyWord,
            @PathVariable("page") Integer page,
            @PathVariable("size") Integer size
    ){
        QueryWrapper<ProductInfo> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.like("product_name", keyWord);
        Page<ProductInfo> pageModel = new Page<>(page,size);
        Page<ProductInfo> resultPage = this.infoService.page(pageModel,queryWrapper1);
        List<SellerProductInfoVO> list = new ArrayList<>();
        for (ProductInfo record : resultPage.getRecords()) {
            SellerProductInfoVO vo = new SellerProductInfoVO();
            BeanUtils.copyProperties(record, vo);
            if(record.getProductStatus() == 1) {
                vo.setStatus(true);
            } else {
                vo.setStatus(false);
            }
            QueryWrapper<ProductCategory> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("category_type", record.getCategoryType());
            ProductCategory productCategory = this.categoryService.getOne(queryWrapper);
            vo.setCategoryName(productCategory.getCategoryName());
            list.add(vo);
        }
        PageVO pageVO = new PageVO();
        pageVO.setContent(list);
        pageVO.setSize(size);
        pageVO.setTotal(resultPage.getTotal());
        return ResultVOUtil.success(pageVO);
    }

    @GetMapping("/findByCategory/{categoryType}/{page}/{size}")
    public ResultVO findByCategory(
            @PathVariable("categoryType") Integer categoryType,
            @PathVariable("page") Integer page,
            @PathVariable("size") Integer size
    ){
        QueryWrapper<ProductInfo> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.like("category_type", categoryType);
        Page<ProductInfo> pageModel = new Page<>(page,size);
        Page<ProductInfo> resultPage = this.infoService.page(pageModel,queryWrapper1);
        List<SellerProductInfoVO> list = new ArrayList<>();
        for (ProductInfo record : resultPage.getRecords()) {
            SellerProductInfoVO vo = new SellerProductInfoVO();
            BeanUtils.copyProperties(record, vo);
            if(record.getProductStatus() == 1) {
                vo.setStatus(true);
            } else {
                vo.setStatus(false);
            }
            QueryWrapper<ProductCategory> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("category_type", record.getCategoryType());
            ProductCategory productCategory = this.categoryService.getOne(queryWrapper);
            vo.setCategoryName(productCategory.getCategoryName());
            list.add(vo);
        }
        PageVO pageVO = new PageVO();
        pageVO.setContent(list);
        pageVO.setSize(size);
        pageVO.setTotal(resultPage.getTotal());
        return ResultVOUtil.success(pageVO);
    }

    @GetMapping("/findById/{id}")
    public ResultVO findById(@PathVariable("id") Integer id){
        ProductInfo productInfo = this.infoService.getById(id);
        if(productInfo == null) throw new ShopException(ResponseEnum.PRODUCT_NULL.getMsg());
        SellerProductVO vo = new SellerProductVO();
        BeanUtils.copyProperties(productInfo, vo);
        if(productInfo.getProductStatus() == 1) {
            vo.setStatus(true);
        } else {
            vo.setStatus(false);
        }
        Map map = new HashMap();
        map.put("categoryType", productInfo.getCategoryType());
        vo.setCategory(map);
        return ResultVOUtil.success(vo);
    }

    @DeleteMapping("/delete/{id}")
    public ResultVO delete(@PathVariable("id") Integer id){
        ProductInfo productInfo = this.infoService.getById(id);
        if(productInfo == null) throw new ShopException(ResponseEnum.PRODUCT_NULL.getMsg());
        boolean removeById = this.infoService.removeById(id);
        if(removeById) return ResultVOUtil.success(null);
        return ResultVOUtil.fail(ResponseEnum.PRODUCT_DELETE_ERROR.getMsg());
    }

    @PutMapping("/updateStatus/{id}/{status}")
    public ResultVO updateStatus(
            @PathVariable("id") Integer id,
            @PathVariable("status") Boolean status
    ){
        ProductInfo productInfo = this.infoService.getById(id);
        if(productInfo == null) throw new ShopException(ResponseEnum.PRODUCT_NULL.getMsg());
        Integer productStatus = 0;
        if(status) {
            productStatus = 1;
        }
        if(productStatus == productInfo.getProductStatus()) throw new ShopException(ResponseEnum.PRODUCT_STATUS_ERROR.getMsg());
        productInfo.setProductStatus(productStatus);
        boolean updateById = this.infoService.updateById(productInfo);
        if(updateById) return ResultVOUtil.success(status);
        return ResultVOUtil.fail(ResponseEnum.PRODUCT_STATUS_UPDATE_ERROR.getMsg());
    }

    @PutMapping("/update")
    public ResultVO update(@RequestBody SellerProductForm productForm){
        ProductInfo productInfo = new ProductInfo();
        BeanUtils.copyProperties(productForm, productInfo);
        if(productForm.getStatus()) {
            productInfo.setProductStatus(1);
        } else {
            productInfo.setProductStatus(0);
        }
        productInfo.setCategoryType(productForm.getCategory().getCategoryType());
        boolean updateById = this.infoService.updateById(productInfo);
        if(updateById) return ResultVOUtil.success(null);
        return ResultVOUtil.fail(ResponseEnum.PRODUCT_UPDATE_ERROR.getMsg());
    }

    @GetMapping("/export")
    public void export(HttpServletResponse response) throws IOException {
        List<ProductInfo> list = infoService.list();
        if (list.isEmpty()) {
            response.setContentType("application/json");
            response.getWriter().write("{\"error\": \"无数据可导出\"}");
            return;
        }

        Map<Integer, String> categoryMap = categoryService.list()
                .stream()
                .collect(Collectors.toMap(ProductCategory::getCategoryType, ProductCategory::getCategoryName));

        List<ProductExcelVO> result = list.stream().map(productInfo -> {
            ProductExcelVO vo = new ProductExcelVO();
            BeanUtils.copyProperties(productInfo, vo);
            vo.setProductStatus(productInfo.getProductStatus() == 1 ? "上架" : "下架");
            vo.setCategoryName(categoryMap.get(productInfo.getCategoryType()));
            return vo;
        }).collect(Collectors.toList());

        String fileName = URLEncoder.encode("商品信息", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");


        try (OutputStream outputStream = response.getOutputStream()) {
            EasyExcel.write(outputStream, ProductExcelVO.class)
                    .registerWriteHandler(new CustomCellWriteHandler())
                    .sheet("商品信息")
                    .doWrite(result);
        } catch (Exception e) {
            response.reset();
            response.setContentType("application/json");
            response.getWriter().write("{\"error\": \"导出失败: " + e.getMessage() + "\"}");
        }
    }


    @PostMapping("/import")
    public ResultVO importData(@RequestParam("file")MultipartFile file){
        List<ProductInfo> productInfoList = null;
        try {
            productInfoList = this.infoService.excleToProductInfoList(file.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        boolean saveBatch = this.infoService.saveBatch(productInfoList);
        if(saveBatch) return ResultVOUtil.success(null);
        return ResultVOUtil.fail(ResponseEnum.FILE_UPLOAD_FAIL.getMsg());
    }
}

